package com.bosssoft.trainee.nontax.service.impl;

import com.bosssoft.trainee.nontax.dao.PermissionDao;
import com.bosssoft.trainee.nontax.dao.RoleDao;
import com.bosssoft.trainee.nontax.dao.RolePermissionDao;
import com.bosssoft.trainee.nontax.dao.UserRoleDao;
import com.bosssoft.trainee.nontax.entity.dto.PermissionDto;
import com.bosssoft.trainee.nontax.entity.dto.RoleDto;
import com.bosssoft.trainee.nontax.entity.dto.TreeNode;
import com.bosssoft.trainee.nontax.entity.po.Permission;
import com.bosssoft.trainee.nontax.entity.po.Role;
import com.bosssoft.trainee.nontax.entity.po.RolePermission;
import com.bosssoft.trainee.nontax.entity.po.UserRole;
import com.bosssoft.trainee.nontax.entity.vo.RoleVo;
import com.bosssoft.trainee.nontax.service.RoleService;
import com.bosssoft.trainee.nontax.util.mapper.dtoVo.RoleDtoVo;
import com.bosssoft.trainee.nontax.util.mapper.poDto.RolePoDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: (Role)表服务实现类
 * @author Luo WenLong
 * @since 2022-06-12 10:16:46
 */
@Slf4j
@Service("roleService")
public class RoleServiceImpl implements RoleService {
    @Resource
    private RoleDao roleDao;

    @Autowired
    private PermissionDao permissionDao;

    @Autowired
    private RolePoDto rolePoDto;

    @Autowired
    private RoleDtoVo roleDtoVo;

    @Autowired
    private RolePermissionDao rolePermissionDao;

    @Autowired
    private UserRoleDao userRoleDao;

    /**
     * @Description: 获取符合要求的所有角色
     * @param role role
     * @return: java.util.List<com.bosssoft.trainee.nontax.entity.vo.RoleVo>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:35
     */
    @Override
    public List<RoleVo> queryAllByRole(RoleDto role) {
        return roleDtoVo.dto2vo(rolePoDto.po2dto(roleDao.queryAllByRole(rolePoDto.dto2po(role))));
    }

    /**
     * @Description: 获取页面的授权角色信息
     * @param pageName page name
     * @return: java.util.Map<java.lang.String,java.util.List<java.lang.String>>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:31
     */
    @Override
    public Map<String, List<String>> getPageRolesByRoles(String pageName) {
        Map<String, List<String>> tagToRoles = new TreeMap<>();
        permissionDao.getPagePermission(pageName).forEach(permission -> tagToRoles.put(
                permission.getOptionTag().replace('-','_'),
                permissionDao.getRolesByPermission(permission.getPermissionId())));
        return tagToRoles;
    }

    /**
     * @Description: 获取所有角色数据用TreeNode模式返回
     * @return: java.util.List<com.bosssoft.trainee.nontax.entity.dto.TreeNode>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:30
     */
    @Override
    public List<TreeNode> queryAllInTreeNodeTemplate() {
        LinkedList<TreeNode> linkedList = new LinkedList<>();
        List<Role> roles = roleDao.queryAllByRole(Role.builder().build());
        roles.forEach(role -> linkedList.add(new TreeNode(role.getRoleId(),role.getRoleName(),null)));
        return linkedList;
    }

    /**
     * @Description: 获取目标用户的手游角色
     * @param userId user id
     * @return: java.util.ArrayList<com.bosssoft.trainee.nontax.entity.vo.RoleVo>
     * @Author: Luo WenLong
     * @Date: 2022/6/26 13:30
     */
    @Override
    public ArrayList<RoleVo> getRolesByUserId(Integer userId) {
        return (ArrayList<RoleVo>) roleDtoVo.dto2vo(rolePoDto.po2dto(roleDao.getRolesByUserId(userId)));
    }

    /**
     * @Description: 通过ID查询单条数据
     * @param roleId 主键
     * @return 实例对象
     */
    @Override
    public RoleVo queryById(Integer roleId) {
        return roleDtoVo.dto2vo(rolePoDto.po2dto(this.roleDao.queryById(roleId)));
    }

    /**
     * @Description: 分页查询
     * @param role 筛选条件
     * @param pageRequest      分页对象
     * @return 查询结果
     */
    @Override
    public Page<Role> queryByPage(RoleDto role, PageRequest pageRequest) {
        long total = this.roleDao.count(rolePoDto.dto2po(role));
        return new PageImpl<>(this.roleDao.queryAllByLimit(rolePoDto.dto2po(role), pageRequest), pageRequest, total);
    }

    /**
     * @Description: 新增数据
     * @param role 实例对象
     * @return 实例对象
     */
    @Override
    public RoleVo insert(RoleDto role) {
        Role rolePo = rolePoDto.dto2po(role);
        if(role.getRoleName() == null || "".equals(role.getRoleName())){
            log.info("add role error, role name can't be null or vacuum");
            return null;
        }
        this.roleDao.insert(rolePo);
        List<Permission> permissions = permissionDao.queryAllByLimit(PermissionDto.builder().build(),PageRequest.of(0,300));
        List<RolePermission> rolePermissions = new ArrayList<>();
        permissions.forEach(permission -> rolePermissions.add(
                RolePermission
                        .builder()
                        .roleId(rolePo.getRoleId())
                        .isValid(1)
                        .permissionId(permission.getPermissionId())
                        .build()));
        this.rolePermissionDao.insertBatch(rolePermissions);
        return roleDtoVo.dto2vo(rolePoDto.po2dto(rolePo));
    }

    /**
     * @Description: 修改数据
     * @param role 实例对象
     * @return 实例对象
     */
    @Override
    public RoleVo update(RoleDto role) {
        this.roleDao.update(rolePoDto.dto2po(role));
        return this.queryById(role.getRoleId());
    }

    /**
     * @Description: 通过主键删除数据
     * @param roleId 主键
     * @return 是否成功
     */
    @Override
    public boolean deleteById(Integer roleId) {
        this.userRoleDao.update(UserRole.builder().roleId(roleId).isValid(1).build());
        this.rolePermissionDao.deleteRolePermissionByRoleId(roleId);
        return this.roleDao.deleteById(roleId) > 0;
    }

    /**
     * @Description: 判断角色能否删除
     * @param roleId role id
     * @return: java.lang.String
     * @Author: Luo WenLong
     * @Date: 2022/6/22 12:24
     */
    @Override
    public String canDeleteRole(Integer roleId) {
        if(roleId == 1 || roleId == 2 || roleId == 3 ){
            return "can't delete this role, no authorization";
        } else {
            return null;
        }
    }
}
